<template>
  <div class="image-upload">
    <el-upload
      :action="uploadAction"
      :headers="uploadHeaders"
      :data="uploadData"
      :show-file-list="false"
      :on-success="handleSuccess"
      :on-error="handleError"
      :before-upload="beforeUpload"
      :on-progress="handleProgress"
      :disabled="uploading"
      :accept="accept"
    >
      <div class="upload-trigger">
        <div v-if="imageUrl" class="image-preview">
          <img :src="imageUrl" alt="preview" />
          <div class="image-mask">
            <el-icon class="mask-icon" @click.stop="handleRemove">
              <Delete />
            </el-icon>
            <el-icon class="mask-icon" @click.stop="handlePreview">
              <ZoomIn />
            </el-icon>
          </div>
        </div>
        <div v-else class="upload-placeholder">
          <el-icon v-if="!uploading" class="upload-icon">
            <Plus />
          </el-icon>
          <el-progress 
            v-if="uploading" 
            type="circle" 
            :percentage="uploadProgress"
            :width="60"
          />
          <div class="upload-text">{{ uploading ? '上传中...' : '点击上传' }}</div>
        </div>
      </div>
    </el-upload>

    <!-- 图片预览对话框 -->
    <el-dialog v-model="previewVisible" title="图片预览" width="60%">
      <img :src="imageUrl" alt="preview" style="width: 100%" />
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, computed, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { Plus, Delete, ZoomIn } from '@element-plus/icons-vue'
import { getFileUrl } from '@/api/file'

const props = defineProps({
  // 图片URL或相对路径
  modelValue: {
    type: String,
    default: ''
  },
  // 文件存储目录前缀
  prefix: {
    type: String,
    default: 'goods'
  },
  // 允许的文件类型
  accept: {
    type: String,
    default: 'image/jpeg,image/jpg,image/png,image/gif'
  },
  // 文件大小限制（MB）
  maxSize: {
    type: Number,
    default: 5
  }
})

const emit = defineEmits(['update:modelValue', 'success', 'error'])

const uploading = ref(false)
const uploadProgress = ref(0)
const previewVisible = ref(false)

// 上传接口地址
const uploadAction = computed(() => {
  return `/customer-api/file/uploadImage/${props.prefix}`
})

const uploadHeaders = computed(() => {
  // 可以添加token等认证信息
  return {}
})

const uploadData = computed(() => {
  return {}
})

// 图片URL
const imageUrl = computed(() => {
  if (!props.modelValue) return ''
  return getFileUrl(props.modelValue)
})

// 上传前校验
const beforeUpload = (file) => {
  // 检查文件类型
  const acceptTypes = props.accept.split(',')
  const isValidType = acceptTypes.some(type => {
    if (type.includes('*')) {
      const mainType = type.split('/')[0]
      return file.type.startsWith(mainType)
    }
    return file.type === type
  })

  if (!isValidType) {
    ElMessage.error(`只能上传 ${props.accept} 格式的图片`)
    return false
  }

  // 检查文件大小
  const isValidSize = file.size / 1024 / 1024 < props.maxSize
  if (!isValidSize) {
    ElMessage.error(`图片大小不能超过 ${props.maxSize}MB`)
    return false
  }

  uploading.value = true
  uploadProgress.value = 0
  return true
}

// 上传进度
const handleProgress = (event) => {
  uploadProgress.value = Math.round(event.percent)
}

// 上传成功
const handleSuccess = (response) => {
  uploading.value = false
  uploadProgress.value = 0

  if (response.code === 200) {
    const filePath = response.data
    emit('update:modelValue', filePath)
    emit('success', filePath)
    ElMessage.success('上传成功')
  } else {
    ElMessage.error(response.msg || '上传失败')
    emit('error', response.msg)
  }
}

// 上传失败
const handleError = (error) => {
  uploading.value = false
  uploadProgress.value = 0
  console.error('上传失败:', error)
  ElMessage.error('上传失败，请重试')
  emit('error', error)
}

// 删除图片
const handleRemove = () => {
  emit('update:modelValue', '')
}

// 预览图片
const handlePreview = () => {
  previewVisible.value = true
}
</script>

<style scoped>
.image-upload {
  display: inline-block;
}

.upload-trigger {
  width: 148px;
  height: 148px;
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: all 0.3s;
}

.upload-trigger:hover {
  border-color: #409eff;
}

.upload-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background-color: #fafafa;
}

.upload-icon {
  font-size: 28px;
  color: #8c939d;
  margin-bottom: 8px;
}

.upload-text {
  font-size: 14px;
  color: #8c939d;
  margin-top: 8px;
}

.image-preview {
  width: 100%;
  height: 100%;
  position: relative;
}

.image-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.image-mask {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 15px;
  opacity: 0;
  transition: opacity 0.3s;
}

.image-preview:hover .image-mask {
  opacity: 1;
}

.mask-icon {
  font-size: 20px;
  color: white;
  cursor: pointer;
  transition: transform 0.3s;
}

.mask-icon:hover {
  transform: scale(1.2);
}
</style>
